From 7ec2f532303617ff075f595f02fb8ae06f9bf1d5 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 24 Nov 2009 14:43:07 +0000 Subject: [PATCH] x86: Add a new physdev_op PHYSDEVOP_setup_gsi for GSI setup. GSI 0-15 is setup by hypervisor, and GSI > =16 is setup by dom0 this physdev_op PHYSDEVOP_setup_gsi. This patch can help dom0 to get rid of intrusive changes of ioapic. Signed-off-by: Xiantao Zhang --- xen/arch/x86/mpparse.c | 11 +++++------ xen/arch/x86/physdev.c | 35 +++++++++++++++++++++++++++++++---- xen/include/public/physdev.h | 13 +++++++++++++ 3 files changed, 49 insertions(+), 10 deletions(-) diff --git a/xen/arch/x86/mpparse.c b/xen/arch/x86/mpparse.c index 33648562ae..fae08764d8 100644 --- a/xen/arch/x86/mpparse.c +++ b/xen/arch/x86/mpparse.c @@ -1122,7 +1122,7 @@ int mp_register_gsi (u32 gsi, int triggering, int polarity) ioapic = mp_find_ioapic(gsi); if (ioapic < 0) { printk(KERN_WARNING "No IOAPIC for GSI %u\n", gsi); - return gsi; + return -EINVAL; } ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base; @@ -1141,12 +1141,12 @@ int mp_register_gsi (u32 gsi, int triggering, int polarity) printk(KERN_ERR "Invalid reference to IOAPIC pin " "%d-%d\n", mp_ioapic_routing[ioapic].apic_id, ioapic_pin); - return gsi; + return -EINVAL; } if ((1<domain, map->index); if ( !irq ) { - dprintk(XENLOG_G_ERR, "dom%d: map pirq with incorrect irq!\n", - d->domain_id); - ret = -EINVAL; - goto free_domain; + if ( IS_PRIV(current->domain) ) + irq = map->index; + else { + dprintk(XENLOG_G_ERR, "dom%d: map pirq with incorrect irq!\n", + d->domain_id); + ret = -EINVAL; + goto free_domain; + } } break; @@ -457,6 +462,28 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg) spin_unlock(&pcidevs_lock); break; } + case PHYSDEVOP_setup_gsi: { + struct physdev_setup_gsi setup_gsi; + + ret = -EPERM; + if ( !IS_PRIV(v->domain) ) + break; + + ret = -EFAULT; + if ( copy_from_guest(&setup_gsi, arg, 1) != 0 ) + break; + + ret = -EINVAL; + if ( setup_gsi.gsi < 0 || setup_gsi.gsi >= nr_irqs_gsi ) + break; + /* GSI < 16 has been setup by hypervisor */ + if ( setup_gsi.gsi >= 16 ) + ret = mp_register_gsi(setup_gsi.gsi, setup_gsi.triggering, + setup_gsi.polarity); + else + ret = -EEXIST; + break; + } default: ret = -ENOSYS; break; diff --git a/xen/include/public/physdev.h b/xen/include/public/physdev.h index 29374024e1..18d30593c6 100644 --- a/xen/include/public/physdev.h +++ b/xen/include/public/physdev.h @@ -227,6 +227,19 @@ struct physdev_op { typedef struct physdev_op physdev_op_t; DEFINE_XEN_GUEST_HANDLE(physdev_op_t); +#define PHYSDEVOP_setup_gsi 21 +struct physdev_setup_gsi { + int gsi; + /* IN */ + uint8_t triggering; + /* IN */ + uint8_t polarity; + /* IN */ +}; + +typedef struct physdev_setup_gsi physdev_setup_gsi_t; +DEFINE_XEN_GUEST_HANDLE(physdev_setup_gsi_t); + /* * Notify that some PIRQ-bound event channels have been unmasked. * ** This command is obsolete since interface version 0x00030202 and is ** -- 2.30.2